#include "server.h"
#include "cmd.h"
#include "sys.h"



volatile u8 is_reset = 0;
volatile u8 conn_cnt = 0;
volatile u8 conn_stat = 0;
HANDLE pipe;

u32 send_pipe_msg(HANDLE ph, int length, void *msg) {
    u32 w_size;
    u32 total_cnt = 0;
    sys_pipe_write(ph, (void *)&length, sizeof(int), &w_size);
    total_cnt += w_size;
    sys_pipe_write(ph, msg, length, &w_size);
    return total_cnt + w_size;
}

u32 recv_pipe_msg(HANDLE ph, void **msg, u32 *len) {
    u32 r_size;
    u32 length;
    u32 total_cnt = 0;
    sys_pipe_read(ph, &length, sizeof(int), &r_size);
    total_cnt += r_size;
    u8 *p_msg = malloc(length);
    sys_pipe_read(ph, p_msg, length, &r_size);
    *msg = p_msg;
    *len = length;
    return total_cnt + r_size;
}



static void cli_watch_dog_thread(void *arg) {
    u8 conn_cnt_prev;
    LOG_WARNNING("dog is going\n");
    while (1) {
        while (conn_stat == 0) {};
        conn_cnt_prev = conn_cnt;
        sys_sleep(2000);
        if (conn_cnt == conn_cnt_prev) {
            LOG_WARNNING("client is dis conn\n");
            conn_stat = 0;
            CloseHandle(pipe);
            if (sys_pipe_create(CLI_PIPE, &pipe) != 0) {
                LOG_WARNNING("handle client dis conn fail!\n");
            } else {
                LOG_WARNNING("handle client dis conn success\n");
            }
            conn_cnt = 0;
            continue;
        }

        // LOG_WARNNING("client is live\n");
    }
}

static int handle_heart_beat(void *msg) {
    conn_stat = 1;
    if (memcmp(msg, "hello", 5) == 0) {
        // LOG_DEBUG("heart beat\n");
        if (conn_cnt == 0xff) {
            conn_cnt = 0;
        } else {
            conn_cnt += 1;
        }
        return 1;
    }
    return 0;
}

static void cli_server_thread(void *arg) {
    LOG_DEBUG("cli server is running...\n");
    extern volatile LOG_LEVEL dbg_switch;
    if (sys_pipe_create(CLI_PIPE, &pipe) != 0) {
        LOG_WARNNING("cli pipe create fail!\n");
    } else {
        LOG_WARNNING("cli pipe create success\n");
    }
    if (sys_wait_client_connect(pipe)) {
        conn_stat = 1;
        LOG_WARNNING("cli client conn success\n");
    }
    u32 read_size;
    u32 cli_len;
    int ret_len;
    void *ret_msg = NULL;
    u8 *cli_buf = NULL;
    char *no_ret_msg = malloc(NO_RET_LEN);
    memcpy(no_ret_msg, NO_RET_MSG, NO_RET_LEN);
    while (1) {
        read_size = recv_pipe_msg(pipe, (void **)&cli_buf, &cli_len);
        if (read_size > 0) {
            if (handle_heart_beat(cli_buf)) continue;
            LOG_DEBUG("cli len=%d, recv msg=%s\n", cli_len - 1, cli_buf); // cli_len - 1是不算最后'\0'的长度
            ret_msg = exec_cmd_func(cli_buf, cli_len - 1, &ret_len);
            LOG_DEBUG("ret len:%d, ret msg:%s\n", ret_len, ret_msg);
            ret_msg = (ret_len  == 0) ? no_ret_msg : ret_msg;
            ret_len = (ret_len == 0) ? NO_RET_LEN : ret_len;
            send_pipe_msg(pipe, ret_len, ret_msg);
            if ((ret_len > 0) && (memcmp(ret_msg, CMD_NOT_FOUND_MSG, CMD_NOT_FOUND_LEN) != 0)) {
                free(ret_msg);
            }
        }
    }
}

net_err_t cli_service_start() {
    if (sys_thread_create(cli_server_thread, (void *)0) == SYS_THREAD_INVALID) {
        LOG_WARNNING("cli_server thread create fail!\n");
        return NET_ERR_SYS;
    }
    // if (sys_thread_create(cli_watch_dog_thread, (void *)0) == SYS_THREAD_INVALID) {
    //     LOG_WARNNING("watch dog thread create fail!\n");
    //     return NET_ERR_SYS;
    // }
    return NET_ERR_OK;
}